/*----------------------------------------------------
Class: plant_1DSOS_RDM
DESCRIPTION:
  This class implements random deposition(RD) with migration(M). The lattice
  is 1D solid-on-solid(SOS).

REFERENCE/BASED ON:
  n_sos_2D_L200_T650.c by Gangshi and Jianqiao
  sos_2d_L100_T700.c

INPUT:
 0 T: Temperature, K
 1 W: deposition rate, layer/s
OUTPUT:
 0 H: average height, layer
 1 R2: roughness square, layer^2
 2 M2: RMS slope square, dimensionless
 3 a: auto-correlation length
STATE:
 * lattice: a 1D array save the height profile.
OPTIONS:
 * 

AUTHOR: Xinyu Zhang (zxy1256@gmail.com)
----------------------------------------------------*/
#ifndef plant_1DSOS_RDM_H
#define plant_1DSOS_RDM_H

#include "Signal.h"

const double EV2KB = 11608.696;
const double KB2H  = 2.08144796e10;

class plant_1DSOS_RDM:public block
{
private:
	// Options
  int   Dim;
  int    Lx;
	int    Ly;
	int    N_CL;
	int    mode;
	double E_D;
	double E_S;
	double E_N;
	
	// Inputs
	double T;
	double W;

	// States
	MCArray*  lattice;
	int**  lattice_stat;
	double *p_migr;
	double *p_desorp;
	double ads_ttl,migr_ttl,desorp_ttl,rate_ttl;
	double MIGR_RT[5];
	double DESORP_RT[5];
	double k_m2d;

	// Outputs
	double h;
	double r2;
	double m2;
	double a;

	// Others
	Spectrum1D* spectrum;
	double* xcov_val;

	// GSL random generator
	const	gsl_rng_type *gsl_T;
	gsl_rng *gsl_r;

	void add_remove_atom(int x, int y, int num);
	void adsorption();
	void migration();
	void desorption();
	double OneMCTime(double r_d);
	void migr_site(int *migr_x,int *migr_y);
	void desorp_site(int *desorp_x,int *migr_y);
	void set_ads_rate(double W_set);
	void set_temperature(double T_set);
	void GetNeighbors(int x,int y, int *xpos,int *ypos);	
	void init_migr_rate();
	void init_desorp_rate();
	void init_p_migr();
	void init_p_desorp();
	void init_local_stat(int x, int y);

	inline int index2D_h(int i,int j){return i*Lx+j;};
	inline int index2D_mode(int m,int n){return m*(mode+1)+n;};

	// The following declaration is to prevent compiler default implementation.
	plant_1DSOS_RDM(const plant_1DSOS_RDM&);
	plant_1DSOS_RDM& operator=(const plant_1DSOS_RDM&);
public:
	plant_1DSOS_RDM(double idt, int iDim, int iLx=100,int iMode = 50,double iE_D = 1.8,double iE_S = 1.2,double iE_N=0.6);
	plant_1DSOS_RDM(const string FileName);
	~plant_1DSOS_RDM();
	
	// The virtual/overrided functions, used with SIMULATION framework
	virtual void update(double sysTime);
	void   reset();
	
	// Override UPDATE from block, for individual simulation without the framework
	void   update(double sysTime,double iT,double iW);
	void   getSnapshot(const string FileName);
	double getM2();
	double getR2();
	
	double getH();
	double getTime(){return time;};
	double getAutoCorLength();
	void   getXCov(const string filename);
};

#endif
